package cn.lovecyy.mockjson.plugins;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.Set;

/**
 * HotDeploy
 *
 * @author Yakir
 */
public class HotDeploy {

	private static String jarAddress = "E:/zzq/IDEA_WS/CalculatorTest/lib/Calculator.jar";

	private static String jarPath = "file:/" + jarAddress;

	/**
	 * 热加载Calculator接口的实现 反射方式
	 */
	public static void hotDeployWithReflect() throws Exception {
		URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { new URL(jarPath) },
				Thread.currentThread().getContextClassLoader());
		Class clazz = urlClassLoader.loadClass("com.nci.cetc15.calculator.impl.CalculatorImpl");
		Calculator calculator = (Calculator) clazz.newInstance();
		int result = calculator.add(1, 2);
		System.out.println(result);
	}

	private static DefaultListableBeanFactory defaultListableBeanFactory;

	public static void setApplicationContext(ApplicationContext applicationContext) {
		defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
	}

	/**
	 * 加入jar包后 动态注册bean到spring容器，包括bean的依赖
	 */
	public static void hotDeployWithSpring() throws Exception {
		Set<String> classNameSet = DeployUtils.readJarFile(jarAddress);
		URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { new URL(jarPath) },
				Thread.currentThread().getContextClassLoader());
		for (String className : classNameSet) {
			Class clazz = urlClassLoader.loadClass(className);
			if (DeployUtils.isSpringBeanClass(clazz)) {
				BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
				defaultListableBeanFactory.registerBeanDefinition(DeployUtils.transformName(className),
						beanDefinitionBuilder.getBeanDefinition());
			}
		}
	}

	/**
	 * 删除jar包时 需要在spring容器删除注入
	 */
	public static void delete() throws Exception {
		Set<String> classNameSet = DeployUtils.readJarFile(jarAddress);
		URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { new URL(jarPath) },
				Thread.currentThread().getContextClassLoader());
		for (String className : classNameSet) {
			Class clazz = urlClassLoader.loadClass(className);
			if (DeployUtils.isSpringBeanClass(clazz)) {
				defaultListableBeanFactory.removeBeanDefinition(DeployUtils.transformName(className));
			}
		}
	}

}
